﻿//===========================================================================================================================
// Cuberry - http://www.cuberry.net
// Copyright (c) 2012
// by Peacequare® - Amir Moussa
//===========================================================================================================================
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or any later version.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// This program is distributed in the hope that it will be useful.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//===========================================================================================================================

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Markup;
using P2.Cuberry.Framework.Helper.Configuration;
using P2.Cuberry.Framework.Helper.DAL;


[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "P2.Cuberry.Framework.Helper")]

namespace P2.Cuberry.Framework.Helper
{
    [MarkupExtensionReturnType(typeof(string))]
    public class TranslateExtension : MarkupExtension
    {
        private string key;
        //public static Dictionary<string, System.Resources.ResourceManager> resman = new Dictionary<string, System.Resources.ResourceManager>();
        private DependencyObject targetObject;
        private DependencyProperty targetProperty;

        public TranslateExtension(string key)
        {
            this.key = key;
            P2Translator.CultureChanged += new EventHandler(Translator_CultureChanged);
        }


        void Translator_CultureChanged(object sender, EventArgs e)
        {
            if (targetObject != null && targetProperty != null)
            {
                targetObject.SetValue(targetProperty, P2Translator.GetResource(key));
            }
        }


        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var targetHelper = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
            targetObject = targetHelper.TargetObject as DependencyObject;
            targetProperty = targetHelper.TargetProperty as DependencyProperty;
            return P2Translator.GetResource(key);
        }

    }

    //----------------------------------------------------------------------------//
    //----------------------------------------------------------------------------//

    public class P2Translator
    {
        internal static event EventHandler CultureChanged;
        private static Dictionary<string, string> _currentResources = null;
        private static Dictionary<string, string> _fallbackResources = null;
        private static Dictionary<string, string> _currentModuleResources = null;
        private static Dictionary<string, string> _fallbackModuleResources = null;

        private static string _currentLanguage = "";
        private static string _currentModule = "";

        public static CultureInfo Culture
        {
            get
            {
                return Thread.CurrentThread.CurrentUICulture;
            }
            set
            {
                Thread.CurrentThread.CurrentUICulture = value;
                //Thread.CurrentThread.CurrentCulture = value;
                if (CultureChanged != null)
                {
                    CultureChanged(null, EventArgs.Empty);
                }
            }
        }


        public static string CultureLanguageFU
        {
            get
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder(Culture.TwoLetterISOLanguageName);
                sb = sb.Replace(sb[0], Char.ToUpper(sb[0]), 0, 1);
                return sb.ToString();
            }
        }


        public static string FallbackLanguageFU
        {
            get
            {
                string lang = ConfigurationSetUp.GetAppConfigValue("FallbackLanguage");
                if (string.IsNullOrEmpty(lang))
                    lang = "En";
                return lang;
            }
        }


        public static void ReloadResources()
        {
            try
            {

                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResourcesSecurity);
                using (SecurityDataClassesDataContext db = new SecurityDataClassesDataContext(connectionString))
                {
                    var curItems = (from res in db.XAppResources
                                    where res.ResourceLanguage == P2Translator.CultureLanguageFU
                                    && (res.ModuleName == null || res.ModuleName == "")
                                    select new { res.ResourceName, res.ResourceText });
                    _currentResources = new Dictionary<string, string>();
                    foreach (var curItem in curItems)
                    {
                        _currentResources[curItem.ResourceName] = curItem.ResourceText;
                    }
                    var curModuleItems = (from res in db.XAppResources
                                    where res.ResourceLanguage == P2Translator.CultureLanguageFU
                                    && (res.ModuleName == ModuleRepository.LoadedModule)
                                    select new { res.ResourceName, res.ResourceText });
                    _currentModuleResources = new Dictionary<string, string>();
                    foreach (var curItem in curModuleItems)
                    {
                        _currentModuleResources[curItem.ResourceName] = curItem.ResourceText;
                    }

                    _fallbackResources = new Dictionary<string, string>();

                    var falItems = (from res in db.XAppResources
                                    where res.ResourceLanguage == P2Translator.FallbackLanguageFU
                                    && (res.ModuleName == null || res.ModuleName == "")
                                    select new { res.ResourceName, res.ResourceText });
                    foreach (var falItem in falItems)
                    {
                        _fallbackResources[falItem.ResourceName] = falItem.ResourceText;
                    }
                    _fallbackModuleResources = new Dictionary<string, string>();

                    var falModuleItems = (from res in db.XAppResources
                                    where res.ResourceLanguage == P2Translator.FallbackLanguageFU
                                    && (res.ModuleName == ModuleRepository.LoadedModule)
                                    select new { res.ResourceName, res.ResourceText });
                    foreach (var falItem in falModuleItems)
                    {
                        _fallbackModuleResources[falItem.ResourceName] = falItem.ResourceText;
                    }
                    _currentLanguage = P2Translator.CultureLanguageFU;
                    _currentModule = ModuleRepository.LoadedModule;

                }
            }
            catch (Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "P2Localization", System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        public static Dictionary<string, string> CurrentResources
        {
            get
            {
                if (P2Translator.CultureLanguageFU != _currentLanguage || _currentResources == null || _currentModule != ModuleRepository.LoadedModule)
                {
                    ReloadResources();
                }
                return _currentResources;
            }
        }


        public static Dictionary<string, string> FallbackResources
        {
            get
            {
                if (P2Translator.CultureLanguageFU != _currentLanguage || _currentResources == null || _currentModule != ModuleRepository.LoadedModule)
                {
                    ReloadResources();
                }
                return _fallbackResources;
            }
        }


        public static Dictionary<string, string> CurrentModuleResources
        {
            get
            {
                if (P2Translator.CultureLanguageFU != _currentLanguage || _currentResources == null || _currentModule != ModuleRepository.LoadedModule)
                {
                    ReloadResources();
                }
                return _currentModuleResources;
            }
        }


        public static Dictionary<string, string> FallbackModuleResources
        {
            get
            {
                if (P2Translator.CultureLanguageFU != _currentLanguage || _currentResources == null || _currentModule != ModuleRepository.LoadedModule)
                {
                    ReloadResources();
                }
                return _fallbackModuleResources;
            }
        }


        public static string GetResource(string resourceName)
        {
            try
            {
                if (P2Translator.CurrentModuleResources != null && P2Translator.CurrentModuleResources.ContainsKey(resourceName))
                    return P2Translator.CurrentModuleResources[resourceName];
                if (P2Translator.CurrentResources != null && P2Translator.CurrentResources.ContainsKey(resourceName))
                    return P2Translator.CurrentResources[resourceName];
                if (P2Translator.FallbackModuleResources != null && P2Translator.FallbackModuleResources.ContainsKey(resourceName))
                    return P2Translator.FallbackModuleResources[resourceName];
                if (P2Translator.FallbackResources != null && P2Translator.FallbackResources.ContainsKey(resourceName))
                    return P2Translator.FallbackResources[resourceName];
                return resourceName;
            }
            catch (Exception ex) //AM:TC
            {             
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "P2Localization", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


    }
}
